#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "queue.h"

/*
函数名称：
    init_queue
说明:
    初始化环形队列
参数:
    queue[in/out]:环形队列指针
	data_size[in]:唤醒队列每个块的内存大小（最好使用sizeof计算）
返回值：
    -1参数错误
    0成功

*/
int init_queue(queue_t * queue,int data_size)
{
    int i = 0;
    if(!queue || data_size <=0)
        return -1;
    //分配存储空间
    for(i = 0;i< QUEUE_MAX_COUNT;i++)
    {
        queue->data_ptr[i] = (void *)malloc(data_size);
        memset(queue->data_ptr[i],0,sizeof(data_size));
    }
    //初始化控制变量
    queue->head = 0;
    queue->tail = 0;
    queue->count = 0;
    queue->data_size = data_size;
    //初始化互斥锁
#if !defined(WIN32)
    pthread_mutex_init(&queue->mtx, NULL);
#else
	InitializeCriticalSection(&queue->mtx);
#endif
    return 0;
}
/*
函数名称
    free_queue
说明
    释放环形队列资源
参数
    queue[in]:环形队列指针
返回值
    -1参数错误
    0成功
*/
int free_queue(queue_t * queue)
{
     int i = 0;
     if(!queue)   
        return -1;
    //加锁
#if !defined(WIN32)
    pthread_mutex_lock(&queue->mtx); 
#else
	EnterCriticalSection(&queue->mtx);
#endif
    //释放内存
    for(i = 0;i<QUEUE_MAX_COUNT;i++)
    {
        if(queue->data_ptr[i])
        {
            free(queue->data_ptr[i]);
            queue->data_ptr[i] = 0;
        }
    }
    //归零控制变量
    queue->head = 0;
    queue->tail = 0;
    queue->count = 0;
    queue->data_size = 0;
#if !defined(WIN32)
    //解锁
    pthread_mutex_unlock(&queue->mtx);
    //销毁互斥锁
    pthread_mutex_destroy(&queue->mtx);
#else
	LeaveCriticalSection(&queue->mtx);
	DeleteCriticalSection(&queue->mtx);
#endif
}
/*
函数名称：
    empty_queue
说明
    清空环形队列的内容
参数
    queue[in]:队列指针
返回值
    -1参数错误
    0 成功
*/
int empty_queue(queue_t * queue)
{
    int i= 0;
    if(!queue)
        return -1;
    //加锁
#if !defined(WIN32)
    pthread_mutex_lock(&queue->mtx);
#else
	EnterCriticalSection(&queue->mtx);
#endif
    //清空内容
    for(i = 0;i<QUEUE_MAX_COUNT;i++)
    {
        if(queue->data_ptr[i])
        {
            memset(queue->data_ptr[i],0,queue->data_size);
        }
    }
    //复位标识量
    queue->head = 0;
    queue->tail = 0;
    queue->count = 0;
    //解锁
#if !defined(WIN32)
    pthread_mutex_unlock(&queue->mtx);
#else
	LeaveCriticalSection(&queue->mtx);
#endif
}
/*
函数名称：
    pop_queue
说明
    数据出队，将数据复制到data指向的存储空间
参数
    queue[in]:循环队列指针
    data[out]:数据存储指针
返回值
    -1参数错误
    -2队列为空
    -3出队失败，对列内存错误
    0 成功
*/
int pop_queue(queue_t * queue,void *data)
{
    if(!queue || !data)
        return -1;
    //加锁
#if !defined(WIN32)
    pthread_mutex_lock(&queue->mtx);
#else
	EnterCriticalSection(&queue->mtx);
#endif
     //判断队列是否为空   
    if(queue->count <= 0)
    {
       //空队列
#if !defined(WIN32)
		pthread_mutex_unlock(&queue->mtx);
#else
		LeaveCriticalSection(&queue->mtx);
#endif
        return -2;
    }
        
     //出队   
    if(queue->data_ptr[queue->head])
    {
        memcpy(data,queue->data_ptr[queue->head], queue->data_size);
        memset(queue->data_ptr[queue->head],0, queue->data_size);
        queue->head++;
        if( queue->head >= QUEUE_MAX_COUNT)
            queue->head = 0;
         queue->count--;   
    }else
    {
        //队列内存错误
 #if !defined(WIN32)
		pthread_mutex_unlock(&queue->mtx);
#else
		LeaveCriticalSection(&queue->mtx);
#endif
        return -3;
    }
    //解锁
#if !defined(WIN32)
    pthread_mutex_unlock(&queue->mtx);
#else
	LeaveCriticalSection(&queue->mtx);
#endif
    return 0;  
}
/*
函数名称：
    push_queue
说明
    数据入队，将data指针空间的数据拷贝到队列中
参数
    queue[in]:队列指针
    data[in]:数据指针
返回值
    -1参数错误
    -2队列已满
    -3队列内存错误
    0成功
*/
int push_queue(queue_t * queue,void *data)
{
    if(!queue || !data)
        return -1;
    //加锁
#if !defined(WIN32)
    pthread_mutex_lock(&queue->mtx);
#else
	EnterCriticalSection(&queue->mtx);
#endif
    //判断是否满队
    if(queue->count >= QUEUE_MAX_COUNT)
    {   
        //满队
 #if !defined(WIN32)
		pthread_mutex_unlock(&queue->mtx);
#else
		LeaveCriticalSection(&queue->mtx);
#endif
         return -2;
    }
      //入队 
     if(queue->data_ptr[queue->tail])
     {
         memcpy(queue->data_ptr[queue->tail],data, queue->data_size);
         queue->tail++;
         if( queue->tail >= QUEUE_MAX_COUNT)
            queue->tail = 0;
        queue->count++;
     }else
     { 
         //队列内存错误
 #if !defined(WIN32)
		pthread_mutex_unlock(&queue->mtx);
#else
		LeaveCriticalSection(&queue->mtx);
#endif
         return -3;
     }
     //解锁
 #if !defined(WIN32)
	pthread_mutex_unlock(&queue->mtx);
#else
	LeaveCriticalSection(&queue->mtx);
#endif
     return 0;
    
}
